const puppeteer = require("puppeteer");

const axios = require("axios");

const fs = require("fs");

const dayjs = require("dayjs");

// ## 爬取图片
// ## 爬取图片
// ## 爬取图片

async function initPuppateer() {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  page.goto(
    "https://www.upupoo.com/bd01?n=20210426043&bd_vid=11724880147497932614"
  );

  // 给定参数
  const type = "国漫天地";

  await page.exposeFunction("downloadImg", downloadImg);
  //  Error: Evaluation failed: TypeError: Cannot read properties of null (reading 'querySelectorAll')
  // 找不到元素的就等待
  await page.waitForSelector('ul[class="wallpaper-tag-list"]');

  // 在这里处理一下 参数 的真正实现的思路吧（先获取映射）
  const paramsIndex = await page.evaluate(() => {
    let map = [];
    const lis = document
      .querySelector('ul[class="wallpaper-tag-list"]')
      .querySelectorAll("li");
    lis.forEach((i) => map.push(i.innerText));
    return map;
  });

  console.log(paramsIndex);

  // 判断参数
  if (type) {
    const btns = await page.$$('ul[class="wallpaper-tag-list"] li');
    await btns[paramsIndex.findIndex((i) => i === type)].click();
  }

  // 处理数据(又要等待，不然没结果)
  await page.waitForSelector('li[class="wallpaper-item"] div img');

  await page.evaluate(() => {
    const images = document.querySelectorAll(
      'li[class="wallpaper-item"] div img'
    );
    images.forEach((img) => {
      // 获取li的img属性
      downloadImg(img.getAttribute("src"));
    });
  });
}

async function downloadImg(url) {
  // 解析类型
  const [name, type] = url.split("theme")[1].split(".");
  const { data } = await axios.get(url, {
    responseType: "arraybuffer", // 务必设置响应类型
  });
  const filename = name.split("/")[1] + "_" + name.split("/")[2];
  fs.writeFile(
    `./demo/img/${filename}.${type}`,
    data,
    "binary",
    function (err) {
      if (err) return console.log("文件保存失败", err);
      console.log("## 保存图片成功", filename + "." + type);
    }
  );
}

// ### 爬取视频
// ### 爬取视频
// ### 爬取视频
var index = 1; // 视频命名用，没有取名称，懒得弄了

async function initVideo() {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  page.goto("https://www.douyin.com/");

  const closebtn = await page.waitForSelector('div[class="dy-account-close"]');
  // 如果有提示登录，则关闭按钮
  if (closebtn) await page.click('div[class="dy-account-close"]');

  await page.exposeFunction("downloadVideo", downloadVideo);

  // 这个是循环几次获取数据（）
  for (const i of new Array(5).fill(0)) {
    await page.evaluate(async () => {
      await downloadVideo(
        document.querySelector("video source").getAttribute("src")
      );
    });
    // 点击下一个视频
    await page.click('div[class="xgplayer-playswitch-next"]');
  }

  await browser.close();
}

async function downloadVideo(src) {
  const { data } = await axios.get(src, {
    responseType: "arraybuffer",
  });
  // 取名
  fs.writeFile(
    `./demo/video/video_${index}.mp4`,
    data,
    "binary",
    function (err) {
      if (err) return console.log("文件保存失败", err);
      console.log("## 保存视频成功");
      index++;
    }
  );
}

// 音频文件 https://tool.liumingye.cn/music/#/artist/6pKL
// 音频文件 https://tool.liumingye.cn/music/#/artist/6pKL
// 音频文件 https://tool.liumingye.cn/music/#/artist/6pKL

// 外部参数
var musicList = [];

async function initMusic() {
  // 定义歌单
  let info = [];

  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto("https://tool.liumingye.cn/music/#/");
  /**
   * 在爬取网络资源时，一定先弄清楚它的资源是怎么来的
   *  该网页使用网络请求
   *
   */

  await page.waitForSelector(
    'div[class="mask absolute inset-0 flex-center bg-[#3c3c3c70] text-white duration-500 transition rounded-lg"]'
  );

  // 随便点击一个歌单
  await page.click(
    'div[class="mask absolute inset-0 flex-center bg-[#3c3c3c70] text-white duration-500 transition rounded-lg"]'
  );

  page.on("response", async (res) => {
    if (res.request().resourceType() === "media") {
      getUrlHash(res.request().url(), info);
    }
    // if (
    //   res.request().url() === "https://api.liumingye.cn/m/api/playlist/info"
    // ) {
    //   console.log("捕获到歌曲列表请求");
    //   // 拿到列表转存，做请求的映射，我就不做这步了，信息我放在 mp3 info.json里，也是通过这个方法拿到的数据
    //   // console.log(await res.text());
    //   info = await res.json();
    // }
  });

  await page.waitForSelector(
    "button[class='arco-btn arco-btn-primary arco-btn-shape-round arco-btn-size-medium arco-btn-status-normal']"
  );

  // 点击播放全部
  await page.click(
    "button[class='arco-btn arco-btn-primary arco-btn-shape-round arco-btn-size-medium arco-btn-status-normal']"
  );

  // 直接点击下一首播放
  for (const i of new Array(20).fill(0)) {
    await delay(4000);

    await page.click(
      'button[class="arco-btn arco-btn-text arco-btn-shape-square arco-btn-size-medium arco-btn-status-normal superellipse"]'
    );
  }

  // 结束后
  console.log(
    `歌曲转存结束,一共保存了${musicList.length}首歌，下面进行歌曲下载`
  );

  await browser.close();

  downloadMusic(musicList);
}
function delay(time) {
  return new Promise(function (resolve) {
    setTimeout(resolve, time);
  });
}

// 绑定外部方法，专门处理 url hash
function getUrlHash(url) {
  if (!url) return;

  let hash = url.split("?")[1]?.split("=")[1].replace("&quality", ""); // url 的请求 hash

  if (!hash) return console.log("歌曲URL不可用"); // hash 值不存在，则表示不是歌曲列表中的请求

  // 找歌曲信息
  // {
  //   "id": "0YXav",
  //   "name": "一生有你",  // 歌名
  //   "artist": [{ "id": "x54Y", "name": "水木年华" }],   歌手
  //   "hash": "b3f634HzOLrfMF9SfoFxvaAaYFEZSwZSByWMoKP4GiqF3T270"  请求
  // },
  const songsList = require("./mp3/info.json");
  const item = songsList.find((i) => i.hash === hash);
  if (item) {
    musicList.push({
      musicUrl: url,
      name: item.name,
      user: item.artist,
    });

    console.log("歌曲转存", item.name);
  }
}

// 歌曲下载
async function downloadMusic(list) {
  for (const item of list) {
    console.log(
      `## 开始下载[第${list.findIndex(
        (i) => i.musicUrl === item.musicUrl
      )}首]歌曲`,
      item.name
    );
    const { data } = await axios.get(item.musicUrl, {
      responseType: "arraybuffer",
    });
    // 取名
    fs.writeFile(`./demo/mp3/${item.name}.mp3`, data, "binary", function (err) {
      if (err) return console.log("歌曲保存失败", err);
      console.log("## 歌曲保存成功");
      index++;
    });
  }
}

initMusic();
